package cn.echo.sharding.config;


import cn.echo.sharding.database.DefaultDataSource;
import cn.echo.sharding.database.MasterSlaveRuleConfig;
import org.apache.shardingsphere.api.config.encrypt.EncryptRuleConfiguration;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

/** 
 * sharding分库表数据源配置
 * @author lonyee
 */
public class DatabaseShardingConfigurator extends AbstractDatabaseConfigSupport {

	 /** sharding分库表数据源配置 */
	 public DataSource dataSource(DefaultDataSource defaultDataSource) throws SQLException {
		 log.info("Initialize sharding dataSource");

		 ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
		 //分表策略
		 shardingRuleConfig.setTableRuleConfigs(this.tableRuleConfigs());
		 //数据脱敏策略
		 shardingRuleConfig.setEncryptRuleConfig(this.encryptRuleConfig());
		 //拆表分组绑定
		 shardingRuleConfig.setBindingTableGroups(this.bindingTableGroups());
		 //广播表列表
		 shardingRuleConfig.setBroadcastTables(this.broadcastTables());
		 //设置默认数据源
		 shardingRuleConfig.setDefaultDataSourceName(defaultDataSource.getDefaultDataSourceName());

		 //转换成Sharding配置
		 Collection<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs = new LinkedList<>();
		 for (MasterSlaveRuleConfig config : defaultDataSource.getMasterSlaveRules()) {
			 masterSlaveRuleConfigs.add(config.parseMasterSlaveRule());
		 }
		 shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs);

		 Map<String, DataSource> dataSourceMap = new HashMap<>();
		 dataSourceMap.putAll(defaultDataSource.getDataSources());

		 return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());
	 }


	/**
	 * 配置分表策略TableRule
	 */
	public Collection<TableRuleConfiguration> tableRuleConfigs() {
		return Collections.emptyList();
	}


	/**
	 * 数据脱敏策略EncryptRule
	 */
	public EncryptRuleConfiguration encryptRuleConfig() {
		return null;
	}

	/**
	 * 配置广播表列表BroadcastTables
	 * 用于数据源分片下，每个数据源都保存相同表全量数据，如字典表，配置表等
	 */
	public Collection<String> broadcastTables() {
		return Collections.emptyList();
	}

	/**
	 * 配置绑定表分组BindingTable
	 * 关联多表查询的时候避免笛卡尔积的组合出现
	 */
	public Collection<String> bindingTableGroups() {
		return Collections.emptyList();
	}

}
